const feathers = require('@feathersjs/feathers');
const errors = require('@feathersjs/errors');
const path = require('path');
const fs = require('fs');

const basePath = process.env.NODE_ENV === 'develop'?{
  conf: 'E:/temp/nginxConfTemp/host',
  ssl: 'E:/temp/nginxConfTemp/cert'
}:{
  conf: '/etc/nginx/host',
  ssl: '/etc/nginx/cert'
};

const sslExtraStr = 'ssl_certificate {{pem}};'+
'ssl_certificate_key {{key}};'+
'ssl_session_timeout 5m;'+
'ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;'+
'ssl_protocols TLSv1 TLSv1.1 TLSv1.2;'+
'ssl_prefer_server_ciphers on;'+
'listen 443 ssl;';

//存储ssl证书
const uploadCertKey = (domain,key)=>{
  try{
    fs.writeFileSync(`${basePath.ssl}/${domain}.key`,key);
    return 1;
  }catch(e){
    return 0;
  }
};
const uploadCertPem = (domain,pem)=>{
  try{
    fs.writeFileSync(`${basePath.ssl}/${domain}.pem`,pem);
    return 1;
  }catch(e){
    return 0;
  }
};
//删除目标目录所有文件
const delPathFiles = (path)=>{
  let files = fs.readdirSync(path);
  if(files.length>0){
    files.forEach(f=>{
      let currentPath = path + '/' + f;
      fs.unlink(currentPath,function(){});
    });
  }
};

//获取conf文件
const getConf = ()=>{
  try{
  //获取conf
    let cfiles = fs.readdirSync(basePath.conf);
    let confPath = null ;
    let confName = '';
    cfiles.forEach(f=>{
      if(f.indexOf('.conf') > -1){
        confPath = basePath.conf + '/' + f ;
        confName = f;
      }
    });
    let conf = null;
    let domain = '';
    if(confPath){
      domain = confName.replace('.conf','');
      let c = fs.readFileSync(confPath);
      conf = c.toString('utf8');
    }
    return {conf,domain} ;
  }
  catch(e){
    return {conf:null,domian:''};
  } 
};
//获取ssl文件
const getssl = (domain)=>{
  let certKey = null;
  let certPem = null;
  if(!domain) return {certKey,certPem};
  let isKeyExists = fs.existsSync(`${basePath.ssl}/${domain}.key`);
  if(isKeyExists){
    let k = fs.readFileSync(`${basePath.ssl}/${domain}.key`);
    certKey = k.toString('utf8');
  }
  let isPemExists = fs.existsSync(`${basePath.ssl}/${domain}.pem`);
  if(isPemExists){
    let p = fs.readFileSync(`${basePath.ssl}/${domain}.pem`);
    certPem = p.toString('utf8');
  }
  return {certKey,certPem};
};

module.exports = {
  before: {
    all: [],
    find: [ctx=>{// get /nginx 获取当前的nginx配置
      let {conf,domain}= getConf();
      let {certKey,certPem} = getssl(domain);
      ctx.result = {
        code: 1,
        message: 'success',
        data:{
          conf: conf,
          ssl:{certKey,certPem}
        }
      };
      return feathers.SKIP;
    }],
    get: [],
    create: [ctx=>{
      //入参判断
      if(!ctx.data.root || !ctx.data.domain || !ctx.data.port) return Promise.reject(new errors.BadRequest('缺乏必要参数'));
      try{
        //读取模板conf
        let model = fs.readFileSync(path.join(__dirname,'../../../config/nginx/default.conf'));
        let confModel = model.toString('utf8');
        //存储ssl证书
        if(ctx.data.ssl && ctx.data.ssl.certKey && ctx.data.ssl.certPem){
          uploadCertKey(ctx.data.domain, ctx.data.ssl.certKey);
          uploadCertPem(ctx.data.domain, ctx.data.ssl.certPem);
          let sslConfig = sslExtraStr.replace('{{key}}',`/etc/nginx/${ctx.data.domain}.key`).replace('{{pem}}',`/etc/nginx/${ctx.data.domain}.pem`);
          confModel = confModel.replace('{{sslConfig}}',sslConfig);
        }else{
          confModel = confModel.replace('{{sslConfig}}','');
        }
        confModel = confModel.replace('{{root}}',ctx.data.root).replace('{{domain}}',ctx.data.domain).replace('{{port}}',ctx.data.port);
        //拼接完成，清空目标目录
        delPathFiles(basePath.conf);
        //写入目标文件
        const p = `${basePath.conf}/${ctx.data.domain}.conf`;
        fs.writeFileSync(p,confModel);
        ctx.result = {
          code: 1,
          message: 'success'
        };
      }catch(e){
        return Promise.reject(new errors.BadRequest(e));
      }
      return feathers.SKIP;
    }],
    update: [ctx=>{
      delPathFiles(basePath.conf);
      delPathFiles(basePath.ssl);
      return ctx.service.create(ctx.data).then(d=>{
        ctx.result = d;
      });
    }],
    patch: [],
    remove: []
  },

  after: {
    all: [],
    find: [],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
  },

  error: {
    all: [],
    find: [],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
  }
};
